<template>
    <div class="compress-container">
        <div class="control-panel">
            <div class="options-panel">
                <div class="quality-input">
                    <span>压缩质量:</span>
                    <n-input-number
                        v-model:value="quality"
                        :min="1"
                        :max="100"
                        :step="1"
                        class="number-input"
                    >
                        <template #suffix>%</template>
                    </n-input-number>
                </div>
                <div class="size-limit">
                    <span>最大尺寸:</span>
                    <n-input-number
                        v-model:value="maxWidth"
                        :min="100"
                        :max="10000"
                        placeholder="宽度"
                        class="size-input"
                    />
                    x
                    <n-input-number
                        v-model:value="maxHeight"
                        :min="100"
                        :max="10000"
                        placeholder="高度"
                        class="size-input"
                    />
                </div>
            </div>
            <n-button @click="clearAll">清空</n-button>
        </div>

        <div class="content-panel">
            <!-- 输入区域 -->
            <div class="input-section">
                <div class="section-header">
                    <span>选择图片</span>
                </div>
                <div class="upload-area">
                    <n-upload
                        :show-file-list="false"
                        accept="image/*"
                        @change="handleFileChange"
                    >
                        <div class="upload-trigger">
                            <template v-if="!selectedFile">
                                <div class="upload-placeholder">
                                    <span>点击或拖拽图片到此处</span>
                                </div>
                            </template>
                            <template v-else>
                                <img :src="previewUrl" alt="Preview" class="preview-image" />
                                <div class="image-info">
                                    <span>{{ selectedFile.name }}</span>
                                    <span class="file-size">({{ formatFileSize(selectedFile.size) }})</span>
                                </div>
                            </template>
                        </div>
                    </n-upload>
                </div>
            </div>

            <!-- 压缩按钮 -->
            <div class="action-panel" v-if="selectedFile">
                <n-button type="primary" @click="compressImage" :loading="compressing">
                    开始压缩
                </n-button>
            </div>

            <!-- 输出区域 -->
            <div class="output-section" v-if="compressedUrl">
                <div class="section-header">
                    <span>压缩结果</span>
                    <div class="actions">
                        <n-button quaternary size="small" @click="downloadImage">
                            下载
                        </n-button>
                        <n-button quaternary size="small" @click="clearOutput">
                            清空
                        </n-button>
                    </div>
                </div>
                <div class="result-preview">
                    <img :src="compressedUrl" alt="Compressed" class="compressed-image" />
                    <div class="compression-info">
                        <span>原始大小: {{ formatFileSize(selectedFile?.size || 0) }}</span>
                        <span>压缩大小: {{ formatFileSize(compressedSize) }}</span>
                        <span>压缩率: {{ compressionRatio }}%</span>
                    </div>
                </div>
            </div>
        </div>
    </div>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import ImageCompressor from 'image-compressor.js'
import view from '@renderer/util/ui/ViewUtil'

// 压缩选项
const quality = ref(60)
const maxWidth = ref(1920)
const maxHeight = ref(1080)

// 文件相关
const selectedFile = ref<File | null>(null)
const previewUrl = ref('')
const compressedUrl = ref('')
const compressedSize = ref(0)
const compressing = ref(false)

// 压缩率计算
const compressionRatio = computed(() => {
    if (!selectedFile.value || !compressedSize.value) return 0
    return Math.round((1 - compressedSize.value / selectedFile.value.size) * 100)
})

// 处理文件选择
const handleFileChange = (data: { file: File }) => {
    if (!data.file || !data.file.file) return
    
    const file = data.file.file as File
    if (!file.type.startsWith('image/')) {
        view.alertErrorMessage('请选择图片文件')
        return
    }

    selectedFile.value = file
    
    // 使用 FileReader 创建 data URL
    const reader = new FileReader()
    reader.onload = (e) => {
        previewUrl.value = e.target?.result as string
    }
    reader.onerror = () => {
        view.alertErrorMessage('图片读取失败')
    }
    reader.readAsDataURL(file)
    
    compressedUrl.value = ''
    compressedSize.value = 0
}

// 压缩图片
const compressImage = async () => {
    if (!selectedFile.value) return
    
    compressing.value = true
    try {
        const compressor = new ImageCompressor()
        const result = await compressor.compress(selectedFile.value, {
            quality: quality.value / 100,
            maxWidth: maxWidth.value,
            maxHeight: maxHeight.value,
            convertSize: 0,
            success(result: Blob) {
                // 将压缩结果转换为 data URL
                const reader = new FileReader()
                reader.onload = (e) => {
                    compressedUrl.value = e.target?.result as string
                    compressedSize.value = result.size
                }
                reader.onerror = () => {
                    view.alertErrorMessage('压缩结果处理失败')
                }
                reader.readAsDataURL(result)
            },
            error(e: Error) {
                throw e
            }
        })
    } catch (error) {
        view.alertErrorMessage('压缩失败')
        console.error('压缩失败:', error)
    } finally {
        compressing.value = false
    }
}

// 下载压缩后的图片
const downloadImage = () => {
    if (!compressedUrl.value || !selectedFile.value) return

    const link = document.createElement('a')
    link.href = compressedUrl.value
    const ext = selectedFile.value.name.split('.').pop() || 'jpg'
    link.download = `compressed_${Date.now()}.${ext}`
    link.click()
}

// 格式化文件大小
const formatFileSize = (bytes: number): string => {
    if (bytes === 0) return '0 B'
    const k = 1024
    const sizes = ['B', 'KB', 'MB', 'GB']
    const i = Math.floor(Math.log(bytes) / Math.log(k))
    return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// 清空输出
const clearOutput = () => {
    compressedUrl.value = ''
    compressedSize.value = 0
}

// 清空所有
const clearAll = () => {
    selectedFile.value = null
    previewUrl.value = ''
    clearOutput()
}
</script>

<style scoped>
.compress-container {
    height: 100%;
    padding: 16px;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.control-panel {
    display: flex;
    gap: 16px;
    padding: 16px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    align-items: flex-start;
}

.options-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 16px;
}

.quality-input,
.size-limit {
    display: flex;
    align-items: center;
    gap: 8px;
}

.quality-input {
    display: flex;
    align-items: center;
    gap: 8px;
}

.size-input {
    width: 100px;
}

.content-panel {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 16px;
    min-height: 0;
}

.input-section,
.output-section {
    flex: 1;
    display: flex;
    flex-direction: column;
    gap: 8px;
    min-height: 0;
}

.section-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
}

.actions {
    display: flex;
    gap: 8px;
}

.upload-area {
    flex: 1;
    min-height: 200px;
}

.upload-trigger {
    height: 200px;
    border: 2px dashed var(--border-color);
    border-radius: 4px;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 8px;
    cursor: pointer;
    transition: border-color 0.3s;
}

.upload-trigger:hover {
    border-color: var(--primary-color);
}

.upload-placeholder {
    color: var(--text-color-3);
}

.preview-image {
    max-width: 100%;
    max-height: 180px;
    object-fit: contain;
}

.image-info {
    margin-top: 8px;
    text-align: center;
    color: var(--text-color-2);
    font-size: 14px;
}

.file-size {
    color: var(--text-color-3);
    margin-left: 8px;
}

.action-panel {
    display: flex;
    justify-content: center;
    padding: 16px 0;
}

.result-preview {
    flex: 1;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 16px;
    padding: 16px;
    border: 1px solid var(--border-color);
    border-radius: 4px;
    min-height: 200px;
}

.compressed-image {
    max-width: 100%;
    max-height: calc(100% - 40px);
    object-fit: contain;
}

.compression-info {
    display: flex;
    gap: 16px;
    color: var(--text-color-2);
    font-size: 14px;
}

.number-input {
    width: 100px;
}
</style>